<?php
class Designer_Project
{
	static public $containers = array(
		'Panel','Tabpanel','Fieldset','Fieldcontainer','Form','Window'
	);
	
	static public $defines = array(
		'Form','Window','Store','Model'
	);
	
	static public $configContainers = array(
		'Form' , 'Fieldcontainer','Fieldset','Window'
	);
	
	/**
	 * Objects tree
	 * @var Tree
	 */
	protected $_tree;
	
	protected $_config = array(
		'namespace'=>'appClasses',
		'runnamespace'=>'appRun'
	);

	public function __construct(){
		$this->_tree = new Tree();
	}
	
	public function addObject($parent, Ext_Object $object){
		$this->_tree->addItem($object->getName(), $parent, $object);
	}
	
	public function removeObject($name){
		$this->_tree->removeItem($name);
	}
	
	public function changeParent($name , $newParent){
		$this->_tree->changeParent($name, $newParent);
	}
	
	public function getConfig(){
		return $this->_config;
	}
	
	public function __get($name){
		if(!isset($this->_config[$name]))
			trigger_error('Invalid config property requested');
		return $this->_config[$name];	
	}
	
	public function __set($name , $value){
		$this->_config[$name] = $value;
	}
	/**
	 * Set item order
	 * @param mixed $id
	 * @param integer $order
	 * @return boolean - success flag
	 */
	public function setItemOrder($id, $order){
		return $this->_tree->setItemOrder($id, $order);
	}
	/**
     * Resort tree Items
     * @param mixed $parentId - optional, resort only item childs
     * default - false (resort all items)
     */
	public function resortItems($parentId = false){
		$this->_tree->resortItems($parentId);
	}
	/**
	 * Check if object exists
	 * @param string $name
	 * @return boolean
	 */
	public function objectExists($name){
		return $this->_tree->itemExists($name);
	}
	/**
	 * Get all objects from project tree
	 * @return array();
	 */
	public function getObjects(){
		return $this->_tree->getItems();
	}
	/**
	 * Get objects tree
	 * @return Tree
	 */
	public function getTree(){
		return $this->_tree;
	}
	/**
	 * Get object by name
	 * @param string $name
	 * @return Ext_Object
	 */
	public function getObject($name){
		$objData = $this->_tree->getItem($name);
		return $objData['data'];
	}
	
	public function getCode()
	{
		$code = $this->_compileJs(0);
		return '
		Ext.ns("'.$this->namespace.'","'.$this->runnamespace.'");
		'.$code['defines'].'
	    '.$code['layout'];
	}
	
	protected function _compileJs($parent)
	{
		echo '1'.'-';
		$definesCode = '';
		$layoutCode ='';
		$items = array();

		if($this->_tree->hasChilds($parent))
		{			
			$childs = $this->_tree->getChilds($parent);
			
			foreach ($childs as $k=>$item)
			{
				$result = $this->_compileItem($item['id'], $item['data'], $item['parent']);
				$definesCode.=$result['defines'];
				$layoutCode.=$result['layout'];
				if($parent!==0 && !empty($result['items'])){
					
				}		
			}
			
		}
		if($parent!==0 && !empty($items)){				
			$parentData = $this->_tree->getItem($parent);
			$parentObject = $parentData['data'];
			$parentObject->items='['.implode(',', $items).']';
		}
		
		return array('defines'=>$definesCode ,'layout'=>$layoutCode);
	}
	
	protected function _compileItem($id , Db_Object $object , $parent)
	{
		$code = $this->_compileJs($item['id']);
		$definesCode=$code['defines'];
		$layoutCode=$code['layout'];
		$items = array();
		
		if(in_array($object->getClass(), self::$defines,true) || $object->isExtendedCompomemt())
		{		
			$definesCode.= $object->getDefineJs($this->namespace);					
			$item = $this->runnamespace.'.'.$object->getName();
			$layoutCode.= $this->runnamespace.'.'.$object->getName().' = Ext.create("'.$this->namespace.'.'.$object->getName().'",{});'."\n";
		}else{
			$layoutCode.= $this->runnamespace.'.'.$object->getName().' = Ext.widget("'.$object->xtype.'",'.$object->getConfig().');'."\n";				
		}
		return array('layout'=>$layoutCode,'defines'=>$definesCode,'item'=>$items);
	}

	public function getRootPanels()
	{
		$list = $this->_tree->getChilds(0);
		$names = array();
		if(!empty($list)){
			foreach($list as $k=>$v){
				$object = $v['data'];
				if(in_array($object->getClass(),self::$containers))
					$names[] = $this->runnamespace.'.'.$object->getName();
			}
		}
		return $names;
	}
}